package com.community.consumer.controller;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.community.common.entity.*;
import com.community.common.entity.vo.UserLoginVo;
import com.community.common.result.Result;
import com.community.common.utils.JwtUtils;
import com.community.common.utils.StringUtils;
import com.community.consumer.config.DES;
import com.community.consumer.entity.resp.GroupGoodResponse;
import com.community.consumer.entity.resp.GroupGoodSkuResoponse;
import com.community.consumer.entity.resp.GroupRecordListResponse;
import com.community.consumer.entity.vo.TipResult;

import com.community.consumer.entity.vo.UrlVo;
import com.community.consumer.service.ConsumerService;
import com.community.consumer.service.impl.InformationImpl;
import lombok.extern.log4j.Log4j2;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/consumer")
@Log4j2
public class ConsumerController {

    @Autowired
    ConsumerService consumerService;

    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Autowired
    HttpServletRequest request;

    @Autowired
    TipCpontroller tipCpontroller;

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    HttpServletResponse response;

    /**
     * 查找可拼团商品
     * @return
     */
    @PostMapping("/findGroupGood")
    public Result<List<GroupGoodResponse>> findGroupGoodList(){
        log.info("请求路径：【{}】，请求方式：【{}】" ,
                request.getRequestURI(),request.getMethod());
        Result<List<GroupGoodResponse>> result = null;
        String groupGoodList = (String) redisTemplate.opsForValue().get("groupGoodList");
        // redis为空查询数据库
        if(StringUtils.isEmpty(groupGoodList)) {
            // 查询数据库
          List<GroupGoodResponse> goodList =  consumerService.findGroupGoodList();
          redisTemplate.opsForValue().set("groupGoodList",JSONObject.toJSONString(goodList));
          result =Result.success(goodList);
          log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                  request.getRequestURI(),request.getMethod(),result);
          return result;
        }
        // 反序列化
        List<GroupGoodResponse> groupGoods = JSONObject.parseArray(groupGoodList, GroupGoodResponse.class);
        result = Result.success(groupGoods);
        log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                request.getRequestURI(),request.getMethod(),result);
        return result;
    }

    /**
     * 是否已参加成功此活动
     * @param groupId
     * @return
     */
    @PostMapping("/findIsJoinGroup/{groupId}")
    public Result<Integer> findIsJoinGroup(@PathVariable String groupId){
        log.info("请求路径：【{}】，请求方式：【{}】,请求参数：【{}】" ,
                request.getRequestURI(),request.getMethod(),groupId);

        Result<Integer> result = null;
        String header = request.getHeader(JwtUtils.TOKEN);
        if(StringUtils.isEmpty(header)) {
          return Result.success(3);
        }
        UserLoginVo userLogin = InformationImpl.findUserLogin(redisTemplate, request);
        GroupRecord groupRecord = consumerService.findIsJoinGroup(userLogin.getId(),groupId);
        // 未参加
        if(groupRecord == null) {
            result = Result.success(1);
        }
        // 已参加
        if(groupRecord!=null){
            result = Result.success(2);
        }
        log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                request.getRequestURI(),request.getMethod(),result);
        return result;

    }

    /**
     * 查找拼团商品的sku
     * @return
     */
    @PostMapping("/findGroupGoodSku/{groupSkuId}")
    public Result<List<GroupGoodSkuResoponse>> findGroupGoodSkuList(@PathVariable Integer groupSkuId) {
        log.info("请求路径：【{}】，请求方式：【{}】,请求参数：【{}】" ,
                request.getRequestURI(),request.getMethod(),groupSkuId);
        // groupSkuId 为 groupId
        Result<List<GroupGoodSkuResoponse>> result = null;
        List<GroupGoodSkuResoponse> groupGoodSkuList = null;
        // 查找redis中的sku信息
        String groupSkuList = (String) redisTemplate.opsForValue().get("groupGoodSku");
        // redis中为空，查询数据库
        if(StringUtils.isEmpty(groupSkuList)) {
            groupGoodSkuList = consumerService.findGroupSkuList();
            redisTemplate.opsForValue().set("groupGoodSku",JSONObject.toJSONString(groupGoodSkuList));
        } else {
            // redis 不为空
            // 反序列化
            groupGoodSkuList = JSONObject.parseArray(groupSkuList,GroupGoodSkuResoponse.class);
        }
        // 过滤出此拼团商品的sku
        List<GroupGoodSkuResoponse> groupSkuListResult = groupGoodSkuList.stream()
                .filter(groupGoodSku ->groupGoodSku.getGroupId().equals(groupSkuId) && groupGoodSku.getDelFlag()==0)
                .collect(Collectors.toList());
        // 返回
        result = Result.success(groupSkuListResult);
        log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                request.getRequestURI(),request.getMethod(),result);
        return result;
    }

    /**
     * 加入拼团
     * @return
     */
    @Transactional
    @PostMapping("/joinGroup")
    public Result<Order> joinGroup(@RequestBody GroupGoodSkuResoponse groupGoodSkuResoponse ){
        log.info("请求路径：【{}】，请求方式：【{}】,请求参数：【{}】" ,
                request.getRequestURI(),request.getMethod(),JSONObject.toJSONString(groupGoodSkuResoponse));
        Result<Order> result = null;
        // 此团的状态
        int groupGood = consumerService.findGroupGood(groupGoodSkuResoponse.getGroupId());
        // 已失效
        if(groupGood == 1) {
            result = Result.error("已满团");
            log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                    request.getRequestURI(),request.getMethod(),result);
            return result;
        }
        // 当前登录人
        UserLoginVo userLogin = InformationImpl.findUserLogin(redisTemplate, request);
        // 查找创建订单成功记录
        Integer flag = 1;
        Order orderRecord = consumerService.findUserOrder(userLogin.getId(),groupGoodSkuResoponse.getGroupId(),flag);
        // 已拼团成功成功，不可重复参与
        if(orderRecord != null) {
            result = Result.error("已拼团成功成功，不可重复参与");
            log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                    request.getRequestURI(),request.getMethod(),result);
            return result;
        }
        flag = 2;
        // 查找是否创建过订单
        Order orderRecordSecond = consumerService.findUserOrder(userLogin.getId(),groupGoodSkuResoponse.getGroupId(),flag);
        if(orderRecordSecond != null) {
            // 已创建过此商品订单
            result = Result.success(orderRecordSecond);
            log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                    request.getRequestURI(),request.getMethod(),result);
            return result ;
        }
        // 未创建过此商品订单
        String num = RandomUtil.randomNumbers(12);
        // 为订单赋值 添加订单
        Order order = new Order();
        num = "ZWT"+num;
        order.setOrderNum(num);
        order.setUserId(userLogin.getId());
        order.setType(1);
        order.setGroupId(groupGoodSkuResoponse.getGroupId());
        order.setPhone(userLogin.getPhone());
        order.setCreateBy(userLogin.getName());
        int flagOnce = consumerService.addOrder(order);

        // 订单详情 添加订单详情
        OrderMore orderMore = new OrderMore();
        orderMore.setOrderNum(num);
        orderMore.setSkuId(groupGoodSkuResoponse.getSkuId());
        orderMore.setPrice(groupGoodSkuResoponse.getPrice());
        orderMore.setPayMoney(groupGoodSkuResoponse.getPrice());
        orderMore.setNumber(1);
        orderMore.setCreateBy(userLogin.getName());
        int flagSecond = consumerService.addOrderMore(orderMore);

        // 添加拼团记录
        // 是否为团长
        int count = consumerService.findGroupRecordCount(order.getGroupId());
        GroupRecord groupRecord = new GroupRecord();
        if(count == 0){
            // 团长
            groupRecord.setIsCommander(0);
        }else {
            // 参与者
            groupRecord.setIsCommander(1);
        }
        groupRecord.setGroupId(order.getGroupId());
        groupRecord.setUserId(order.getUserId());
        groupRecord.setOrderNum(order.getOrderNum());
        // 添加 参与中的拼团记录
        int flagThird = consumerService.addOrderRecord(groupRecord);

        if(flagOnce + flagSecond < 2) {
            result = Result.error();
            log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                    request.getRequestURI(),request.getMethod(),result);
            return result;
        }
        result = Result.success(order);

        log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                request.getRequestURI(),request.getMethod(),result);
        return result;
    }

    /**
     * 拼团成功
     * @param order
     * @return
     */
    @PostMapping("/joinGroupOverPay")
    public Result<String> joinGroupOverPay(@RequestBody Order order){
        log.info("请求路径：【{}】，请求方式：【{}】,请求参数：【{}】" ,
                request.getRequestURI(),request.getMethod(),JSONObject.toJSONString(order));

        Result<String> result = null;
        RLock lock = redissonClient.getLock("SUCCESS_PAY");
        try {
            boolean b = lock.tryLock();
            if(!b) {
               return result = Result.error("获取锁失败");
            }
            lock.lock(2,TimeUnit.SECONDS);
            // 拼团失败 参与途中人数满员
            if(order.getDelFlag() == 9){
                TipResult tipResult = new TipResult();
                result = Result.success("拼团失败，若已支付，请等待退款");
                tipResult.setTip(result.getData());
                tipResult.setUserId(order.getUserId());
                tipCpontroller.sendMessage(tipResult);
            }
            // 修改订单状态
            int flag = consumerService.updateGroupStatus(order);
            // 拼团失败  ！=2：修改状态失败
            if(flag + order.getDelFlag() != 2){
                TipResult tipResult = new TipResult();
                result = Result.success("拼团失败，若已支付，请等待退款");
                tipResult.setTip(result.getData());
                tipResult.setUserId(order.getUserId());
                tipCpontroller.sendMessage(tipResult);
            }
            // 拼团成功
            if(flag + order.getDelFlag() == 2) {
                consumerService.updateGroupSkuNum(order.getOrderNum());
                result = Result.success("拼团成功，请等待满员");
                TipResult tipResult = new TipResult();
                tipResult.setTip(result.getData());
                tipResult.setUserId(order.getUserId());
                tipCpontroller.sendMessage(tipResult);
            }
            log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                    request.getRequestURI(),request.getMethod(),result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 是否还是锁定状态
            if(lock.isLocked()){
                // 是否是当前执行线程的锁
                if(lock.isHeldByCurrentThread()){
                    // 释放锁
                    lock.unlock();
                }
            }
        }
        return result;
    }

    /**
     * 查找拼团记录
     * @param groupId
     * @return
     */
    @PostMapping("/findGroupRecordList/{groupId}")
    public Result<List<GroupRecordListResponse>> findGroupRecordList(@PathVariable String groupId){
        log.info("请求路径：【{}】，请求方式：【{}】" ,
                request.getRequestURI(),request.getMethod());

        Result<List<GroupRecordListResponse>> result = consumerService.findGroupRecord(groupId) ;
        log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                request.getRequestURI(),request.getMethod(),result);
        return result;
    }


    /**
     * 查找当前登录人
     * @return
     */
    @PostMapping("/findUser")
    public Result<UserLoginVo> findUser() {
        log.info("请求路径：【{}】，请求方式：【{}】" ,
                request.getRequestURI(),request.getMethod());
        UserLoginVo userLogin = InformationImpl.findUserLogin(redisTemplate, request);

        Result<UserLoginVo> result = Result.success(userLogin);
        log.info("请求路径：【{}】，请求方式：【{}】,响应结果：【{}】" ,
                request.getRequestURI(),request.getMethod(),result);
        return result;
    }

    /**
     * 分享链接 数据加密
     * @return
     */
    @PostMapping("/shareUrl")
    public Result<String> shareUrl(@RequestBody UrlVo url){
        log.info("请求路径：【{}】，请求方式:【{}】，请求参数：【{}】",
                request.getRequestURI(),request.getMethod(),JSONObject.toJSONString(url));
        Result<String> result = null;
        //http://zwt.nat300.top/#/consumer/homePage?redirect=%2Fconsumer%2FhomePage/1
        String[] split = url.getUrl().split("/");
        url.setUrl(url.getUrl().replace(split[2],"zwt.nat300.top"));
        int length = split.length;
        // 加密
        String encrypt = DES.encrypt("zhangYuJi", split[length - 1]);
        // 赋值
        url.setUrl(url.getUrl().replace(split[length-1],encrypt));
        System.out.println(url);
        result = Result.success(url.getUrl());
        log.info("请求路径：【{}】，请求方式:【{}】，响应结果：【{}】",
                request.getRequestURI(),request.getMethod(),result);
        return result;
    }

    /**
     * 链接数据解密
     * @param url
     * @return
     */
    @PostMapping("/findGroupGoodByUrl")
    public Result<GroupGoodResponse> findGroupGoodByUrl(@RequestBody UrlVo url){
        log.info("请求路径：【{}】，请求方式:【{}】，请求参数：【{}】",
                request.getRequestURI(),request.getMethod(),JSONObject.toJSONString(url));
        Result<GroupGoodResponse> result = Result.success();
        //http://zwt.nat300.top/#/consumer/homePage?redirect=%2Fconsumer%2FhomePage/1
        String[] split = url.getUrl().split("%2F");
        int length = split.length;
        String key = split[length-1].replace("%","=");
        String[] split1 = key.split("=");
        System.out.println(key);
        //解密
        String decrypt = DES.decrypt("zhangYuJi", split1[0]);
        GroupGoodResponse groupGoodResponse = consumerService.findGroupGoodOne(decrypt);
        if(groupGoodResponse != null){
            result = Result.success(groupGoodResponse);
        }
        log.info("请求路径：【{}】，请求方式:【{}】，响应结果：【{}】",
                request.getRequestURI(),request.getMethod(),result);
        return result;
    }

    /**
     * 跳转路由
     * @return
     */
    @PostMapping("/goUrl")
    public Result<String> goUrl(){
        log.info("请求路径：【{}】，请求方式:【{}】",
                request.getRequestURI(),request.getMethod());
        Result<String> result = null;
        UserLoginVo userLogin = InformationImpl.findUserLogin(redisTemplate, request);
        String url = (String) redisTemplate.opsForValue().get("url:" + userLogin.getId());
        redisTemplate.delete("url:"+userLogin.getId());
        if(StringUtils.isEmpty(url)){
            result = Result.success();
            log.info("请求路径：【{}】，请求方式:【{}】，响应结果：【{}】",
                    request.getRequestURI(),request.getMethod(),result);
            return result;
        }
        result = Result.success(url);
        log.info("请求路径：【{}】，请求方式:【{}】，响应结果：【{}】",
                request.getRequestURI(),request.getMethod(),result);
        return result;
    }
}
